import dayjs from "dayjs";

/**
 * Check if an element has a class
 * @param {HTMLElement} ele
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele: HTMLElement, cls: string) {
  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}

/**
 * Add class to element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function addClass(ele: HTMLElement, cls: string) {
  if (!hasClass(ele, cls)) ele.className += " " + cls;
}

/**
 * Remove class from element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function removeClass(ele: HTMLElement, cls: string) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
    ele.className = ele.className.replace(reg, " ");
  }
}

/**
 * 判断是否是外部链接
 *
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path: string) {
  const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
  return isExternal;
}

/**
 * 格式化增长率，保留两位小数 ，并且去掉末尾的0  取绝对值
 *
 * @param growthRate
 * @returns
 */
export function formatGrowthRate(growthRate: number) {
  if (growthRate === 0) {
    return "-";
  }

  const formattedRate = Math.abs(growthRate * 100)
    .toFixed(2)
    .replace(/\.?0+$/, "");
  return formattedRate + "%";
}

/**
 * 验证手机号
 *
 * @param phoneStr
 * @returns
 */
export function isPhoneNumber(phoneStr: string) {
  const mobile = /^(1\d{10})$/;
  return mobile.test(phoneStr);
}

/**
 * 将文本复制到剪贴板。
 *
 * @param {string} text - 要复制的文本内容。
 * @returns {Promise<void>} - 返回一个 Promise，成功时解析为 undefined，失败时拒绝。
 * @throws {Error} - 如果文本为空或浏览器不支持剪贴板 API，则抛出错误。
 * @example
 * copyText('Hello, World!')
 *   .then(() => {
 *     console.log('文本已成功复制到剪贴板');
 *   })
 *   .catch((error) => {
 *     console.error('复制文本时出错:', error);
 *   });
 */
export function copyText(text: string) {
  const handleError = (message: string) => {
    ElMessage.error(message);
    return Promise.reject(message);
  };
  if (!text) {
    return handleError("请选择复制的内容");
  }
  if (!navigator.clipboard) {
    return handleError("当前浏览器不支持复制");
  }
  return navigator.clipboard
    .writeText(text)
    .then(() => {
      ElMessage.success("复制成功");
    })
    .catch(() => {
      handleError("复制失败");
    });
}
/**
 * 判断是否为字符串
 * @param value 需要判断的值
 * @returns 是否为字符串
 */
export function isString(value: unknown): value is string {
  return typeof value === "string";
}

/**
 * 判断是否为数字
 * @param value 需要判断的值
 * @returns 是否为数字
 */
export function isNumber(value: unknown): value is number {
  return typeof value === "number";
}

/**
 * 判断是否为布尔值
 * @param value 需要判断的值
 * @returns 是否为布尔值
 */
export function isBoolean(value: unknown): value is boolean {
  return typeof value === "boolean";
}

/**
 * 判断是否为对象
 * @param value 需要判断的值
 * @returns 是否为对象
 */
export function isObject(value: unknown): value is object {
  return typeof value === "object" && value !== null;
}

/**
 * 判断是否为数组
 * @param value 需要判断的值
 * @returns 是否为数组
 */
export function isArray(value: unknown): value is any[] {
  return Array.isArray(value);
}
/**
 * 从对象中移除指定的字段
 * @param obj 原始对象
 * @param keysToRemove 需要移除的字段数组
 * @returns 移除字段后的新对象
 */
export function removeFields<T extends Record<string, any>, K extends keyof T>(
  obj: T,
  keysToRemove: K[]
): Omit<T, K> {
  return Object.keys(obj).reduce(
    (acc, key) => {
      if (!keysToRemove.includes(key as K) && (obj[key] || isNumber(obj[key]))) {
        (acc as Record<string, any>)[key] = obj[key];
      }
      return acc;
    },
    {} as Omit<T, K>
  );
}
/**
 * 格式化时间
 * @param date 时间（可以是 Date 对象、时间戳或字符串）
 * @param format 格式（默认为 'YYYY-MM-DD HH:mm:ss'）
 * @returns 格式化后的时间字符串
 */
export function formatDate(
  date: Date | number | string,
  format: string = "YYYY-MM-DD HH:mm:ss"
): string {
  return dayjs(date).format(format);
}

/**
 * 格式化时间为友好显示（如 "刚刚"、"1分钟前"）
 * @param date 时间（可以是 Date 对象、时间戳或字符串）
 * @returns 友好显示的时间字符串
 */
export function formatDateFriendly(date: Date | number | string): string {
  const now = dayjs();
  const target = dayjs(date);
  const diffInSeconds = now.diff(target, "second");
  const diffInMinutes = now.diff(target, "minute");
  const diffInHours = now.diff(target, "hour");
  const diffInDays = now.diff(target, "day");

  if (diffInSeconds < 60) {
    return "刚刚";
  } else if (diffInMinutes < 60) {
    return `${diffInMinutes}分钟前`;
  } else if (diffInHours < 24) {
    return `${diffInHours}小时前`;
  } else if (diffInDays === 1) {
    return "昨天";
  } else if (diffInDays === 2) {
    return "前天";
  } else if (diffInDays <= 7) {
    return `${diffInDays}天前`;
  } else {
    return formatDate(date, "YYYY-MM-DD");
  }
}
/**
 * 数字千分位格式化函数
 * @param num 需要格式化的数字/字符串
 * @param decimalPlaces 保留小数位数（默认不处理）
 * @param emptyPlaceholder 无效值占位符
 * @returns 格式化后的字符串
 */
export const formatNumberWithCommas = (
  num: number | string,
  decimalPlaces?: number,
  emptyPlaceholder: string = "-"
): string => {
  // 处理空值
  if (num === null || num === undefined || num === "") return emptyPlaceholder;

  // 统一转换为字符串
  const numStr = String(num).trim();

  try {
    // 解析为数值
    const number = parseFloat(numStr);
    if (isNaN(number)) return emptyPlaceholder;

    // 处理小数位数
    let [integerPart, decimalPart] = number.toFixed(decimalPlaces).split(".");

    // 处理符号
    let sign = "";
    if (integerPart.startsWith("-")) {
      sign = "-";
      integerPart = integerPart.slice(1);
    }

    // 添加千分位逗号
    const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");

    // 组合最终结果
    return decimalPart ? `${sign}${formattedInteger}.${decimalPart}` : `${sign}${formattedInteger}`;
  } catch {
    return emptyPlaceholder;
  }
};
